open Ast
open Gen

type register = 
  | Registre of int
  | RegNom of string

type frame = {
	 name : string;			                (* Nom *)
    lentry : label;        	          (* Label d'entrée *)
    lreturn : label; 			            (* Label de sortie *)
    args : register list;  	          (* Registres temporaires d'arguments *)
    result : register; 		            (* Registre temporaire du résultat (ou rien) *)
    mutable stack : int;              (* Taille nécessaire sur la pile *)
}

type iOperateur = 
  | IPlus
  | IMoins
  | IMult
  | IDiv
  

type iComparateur = 
  | IInf
  | ISup
  | IInfEgal
  | ISupEgal
  | ICompEgal
  | IDiff

type iBoolean =
  | ITrue
  | IFalse
  | ICmp of iExpression * iComparateur * iExpression
  | INotBoolean of iBoolean
  | IOr of iBoolean * iBoolean
  | IAnd of iBoolean * iBoolean

and iFunCall =
	IFunCall of string * iExpression list

and iEgal =
	  IRegCons of register * int
	| IRegFunc of register * iFunCall
	| IRegExpr of register * iExpression

and iBlock = IBlock of label * iStatement

and iExpression =
	| IConstante of int
	| IUnop of iExpression
	| IBinop of iExpression* iOperateur * iExpression
	| IRegister of register
	| IComparator of iExpression * iComparateur * iExpression

and iStatement = 
	| IJumpIf of iJumpIf
  | IJumpWhile of iJumpWhile
	| IEgal of iEgal
	| IGoto of label
	| INop
	| IFunc of iFunCall
 	| IStatements of iStatement list
	| IBlockStatement of iBlock

and iJumpIf = {
  testIf: iBoolean;
  labelThen: label;
  labelElse: label;
  labelEndif: label;
  blockThen: iBlock;
  blockElse: iBlock;
}

and iJumpWhile = {
  labelTest: label;
  testWhile: iBoolean;
  labelLoop: label;
  labelEnd: label;
  blockLoop: iBlock;
}

and iFrame =
	BlockFrame of frame * iBlock
;;

type iProgramme = {
	text: iBlock;
	mutable frames : iFrame list
}
